package com.scene.q1_Basic;

// 抽象类：不能被实例化，可包含抽象方法和具体方法
abstract class Animal {
    // 成员变量
    protected String name;

    // 构造方法（抽象类可以有构造方法，供子类调用）
    public Animal(String name) {
        this.name = name;
    }

    // 抽象方法：只有声明，没有实现，子类必须重写
    public abstract void eat();

    // 具体方法：有完整实现，子类可直接使用或重写
    public void sleep() {
        System.out.println(name + "在睡觉");
    }
}

// 子类继承抽象类：必须实现所有抽象方法
class Dog extends Animal {
    public Dog(String name) {
        super(name); // 调用父类构造方法
    }

    // 实现父类的抽象方法
    @Override
    public void eat() {
        System.out.println(name + "在吃骨头");
    }

    // 重写父类的具体方法
    @Override
    public void sleep() {
        System.out.println(name + "趴着睡觉");
    }

    // 子类特有方法
    public void bark() {
        System.out.println(name + "在汪汪叫");
    }
}

// 另一个子类
class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void eat() {
        System.out.println(name + "在吃小鱼干");
    }

    // 不重写sleep()，使用父类的实现
}

// 抽象子类：可以不实现父类的抽象方法
abstract class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }

    // 未实现父类的eat()方法，因此自身必须声明为抽象类
    public abstract void fly(); // 新增抽象方法
}

public class AbstractClassDemo {
    public static void main(String[] args) {
        // 1. 抽象类不能直接实例化（编译报错）
        // Animal animal = new Animal("动物");

        // 2. 通过子类实例化，体现多态性
        Animal dog = new Dog("旺财");
        Animal cat = new Cat("咪咪");

        // 3. 调用方法（抽象方法已被实现，具体方法可能被重写）
        dog.eat();   // 调用Dog实现的eat()
        dog.sleep(); // 调用Dog重写的sleep()
        ((Dog) dog).bark(); // 调用子类特有方法（需强制类型转换）

        cat.eat();   // 调用Cat实现的eat()
        cat.sleep(); // 调用父类Animal的sleep()

        // 4. 抽象子类也不能实例化
        // Bird bird = new Bird("麻雀");
    }
}
